/*
 * 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.edu.pucp.Envios.DAO;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import pe.edu.pucp.Modelo.Aeropuerto;
import pe.edu.pucp.Modelo.Ciudad;
import pe.edu.pucp.Modelo.Cliente;
import pe.edu.pucp.Modelo.Continente;
import pe.edu.pucp.Modelo.Envio;
import pe.edu.pucp.Modelo.EstadoEnvio;
import pe.edu.pucp.Modelo.EstadoItinerario;
import pe.edu.pucp.Modelo.EstadoNotaCredito;
import pe.edu.pucp.Modelo.EstadoPaquete;
import pe.edu.pucp.Modelo.EstadoVuelo;
import pe.edu.pucp.Modelo.Inventario;
import pe.edu.pucp.Modelo.Itinerario;
import pe.edu.pucp.Modelo.Moneda;
import pe.edu.pucp.Modelo.NotaCredito;
import pe.edu.pucp.Modelo.Pais;
import pe.edu.pucp.Modelo.Paquete;
import pe.edu.pucp.Modelo.Pronostico;
import pe.edu.pucp.Modelo.TipoEscala;
import pe.edu.pucp.Modelo.TipoMovimiento;
import pe.edu.pucp.Modelo.Usuario;
import pe.edu.pucp.Modelo.Vuelo;
import pe.edu.pucp.Util.Constante;
import pe.edu.pucp.Util.HibernateUtil;
import pe.edu.pucp.sigepa.recocidosimulado.domain.interfaz.Solucion;

/**
 *
 * @author pachon
 */
public class EnviosDAO {
    
    public Envio GuardarEnvio(Cliente c, Usuario user, String direccion, String Receptor, String paquetes, Ciudad ciudad){
        Envio envio = new Envio();
        EstadoEnvio estado = new EstadoEnvio();
        estado.setIdestado(Constante.ESTADO_ENVIO_REGISTRADO);
        envio.setCliente(c);
        envio.setDireccion(direccion);
        envio.setUsuario(user);
        envio.setReceptor(Receptor);
        envio.setPuntaje(0);
        envio.setNumpack(Integer.parseInt(paquetes));
        envio.setNumpacklost(0);
        envio.setFechareg(new Date());
        envio.setEstadoEnvio(estado);
        envio.setCosto(envio.getNumpack()*2);
        envio.setAeropuerto(user.getAeropuerto());
        //INventario
        Inventario inventario = new Inventario();
        TipoMovimiento m = new TipoMovimiento();
        m.setIdtipomov(Constante.TIPO_MOVIMIENTO_ENTRADA);
        Aeropuerto aero = buscaAeropuerto(ciudad);            
        inventario.setAeropuerto(aero);
        inventario.setUsuario(user);
        inventario.setEnvio(envio);
        inventario.setTipoMovimiento(m);
        inventario.setFechareg(new Date());

        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
   
        EstadoPaquete estadoPaquete = new EstadoPaquete();
        estadoPaquete.setIdestado(Constante.ESTADO_PAQUETE_ALMACEN);
        session.save(envio);        
        session.save(inventario);
            
        for(int i=0; i<Integer.parseInt(paquetes); i++){
            Paquete paquete = new Paquete();
            paquete.setEnvio(envio);
            paquete.setEstadoPaquete(estadoPaquete);        
            //paquetesEnvio.add(paquete);
            session.save(paquete);
        }
        //envio.setPaquetes(paquetesEnvio);        
        
        //registrar
        tx.commit();
        session.close();
        return envio;
    }
    
    public void actualizarEnvio(Envio envio,Integer id) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction(); 
            EstadoEnvio e = new EstadoEnvio();
            e.setIdestado(id);
            envio.setEstadoEnvio(e);
            session.update(envio);
        tx.commit();
        session.close();
    }
    
    public Aeropuerto buscaAeropuerto(Ciudad ciudad){
        Aeropuerto aero = new Aeropuerto();        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        Query query = session.createQuery("select aero from Aeropuerto aero where aero.ciudad.idciudad = :idCiudad");
        query.setParameter("idCiudad", ciudad.getIdciudad());
        List lista =query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Aeropuerto c = (Aeropuerto) iter.next();
            aero =c;
        }
        tx.commit();
        session.close();
        return aero;
    }
    
    public Moneda buscaMoneda(Pais pais){
        Moneda moneda = new Moneda();        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        Query query = session.createQuery("select moneda from Moneda moneda, Divisa where divisa.pais.idpais = :idPais and divisa.moneda.idmoneda = moneda.idmoneda");
        query.setParameter("idPais", pais.getIdpais());
        List lista =query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Moneda c = (Moneda) iter.next();
            Hibernate.initialize(c.getNombre());
            Hibernate.initialize(c.getCambio());
            Hibernate.initialize(c.getSimbolo());
            Hibernate.initialize(c.getUnidad());
            moneda =c;
        }
        tx.commit();
        session.close();
        return moneda;
    }
    
    public ArrayList<EstadoEnvio> listarEstadosEnvio(){
        ArrayList<EstadoEnvio> lstEstados = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
  
        List lista = session.createQuery("from EstadoEnvio").list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            EstadoEnvio c = (EstadoEnvio) iter.next();
            lstEstados.add(c);
        }
        tx.commit();
        session.close();
        
        
        return lstEstados;
    }
    
    public ArrayList<Vuelo> listarVuelos(Usuario user){
        ArrayList<Vuelo> lstVuelos = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        Query query = session.createQuery("select vuelo from Vuelo vuelo where vuelo.aeropuertoByIddestino.ciudad.idciudad = :idCiudad");
        query.setParameter("idCiudad", user.getAeropuerto().getCiudad().getIdciudad());        
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Vuelo c = (Vuelo) iter.next();
            lstVuelos.add(c);
        }
          
        tx.commit();
        session.close();
        
        return lstVuelos;
    }
    
    public ArrayList<EstadoVuelo> listarEstadosVuelo(){
        ArrayList<EstadoVuelo> lstEstados = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
  
        List lista = session.createQuery("from EstadoVuelo").list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            EstadoVuelo c = (EstadoVuelo) iter.next();
            lstEstados.add(c);
        }
        tx.commit();
        session.close();        
        
        return lstEstados;
    }
    
    
    public ArrayList<Continente> listarContinentes(){
        ArrayList<Continente> lstContinentes = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
  
        String q = "select continente from Continente continente where idcontinente in (:ideu,:idam) order by idcontinente";
        Query query = session.createQuery(q);
        query.setParameter("ideu", Constante.CONTINENTE_EUROPA);
        query.setParameter("idam", Constante.CONTINENTE_SUDAMERICA);
        List lista = query.list();

        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Continente c = (Continente) iter.next();
            lstContinentes.add(c);
        }
        tx.commit();
        session.close();        
        
        return lstContinentes;
    }
    
    public ArrayList<Pais> listarPaises(Continente continente){
        ArrayList<Pais> lstPais = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        
        Query query = session.createQuery("select pais from Pais pais where pais.continente.idcontinente = :idContinente");
        query.setParameter("idContinente", continente.getIdcontinente());
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Pais c = (Pais) iter.next();
            lstPais.add(c);
        }
        tx.commit();
        session.close();        
        
        return lstPais;
    }
    
    public ArrayList<Ciudad> listarCiudades(Pais pais){
        ArrayList<Ciudad> lstCiudad = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        Query query = session.createQuery("select ciudad from Ciudad ciudad, Aeropuerto aeropuerto where ciudad.pais.idpais = :idPais and ciudad.idciudad = aeropuerto.ciudad.idciudad");
        query.setParameter("idPais", pais.getIdpais());
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Ciudad c = (Ciudad) iter.next();
            lstCiudad.add(c);
        }
        tx.commit();
        session.close();        
        
        return lstCiudad;
    }
    
    /////////////////administrar envios
    
    public ArrayList<Vuelo> listarVuelosLlegados(Ciudad ciudad){
        ArrayList<Vuelo> lstVuelos = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        
        Query query = session.createQuery("select vuelo from Vuelo vuelo where vuelo.aeropuertoByIddestino = :idCiudadDestino");
        query.setParameter("idCiudadDestino", ciudad.getIdciudad());
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Vuelo c = (Vuelo) iter.next();
            lstVuelos.add(c);
        }
          
        tx.commit();
        session.close();
        
        return lstVuelos;
    }
    public ArrayList<Itinerario> listarVuelosBusquedaEntrada(Vuelo vuelo, EstadoEnvio estado, String cliente, Usuario user){
        ArrayList<Itinerario> lstItinerarios = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        

        String desc = "select itinerario from Vuelo vuelo, Itinerario itinerario where itinerario.vuelo.aeropuertoByIddestino.ciudad.idciudad = :idCiudad and itinerario.estadoItinerario.idestado = 3 and vuelo.idvuelo = itinerario.vuelo.idvuelo ";//idestado 3 = recorrido
        if (vuelo !=null){
            desc += "and vuelo.idvuelo = :idVuelo and itinerario.vuelo.idvuelo = :idVuelo ";
        }            
        if (estado !=null){
            desc += "and itinerario.envio.estadoEnvio.idestado = :idestado ";
        }            
        if (cliente != null){
            desc += "and (itinerario.envio.cliente.nombre like '%' || :cliente || '%' or itinerario.envio.cliente.apmaterno like '%' || :cliente || '%' or itinerario.envio.cliente.appaterno like '%' || :cliente || '%')";            
        }                           
        
        Query query = session.createQuery(desc);
        
        if (vuelo !=null){
            query.setParameter("idVuelo", vuelo.getIdvuelo());
        }            
        if (estado !=null){
            query.setParameter("idestado", estado.getIdestado());
        }            
        if (cliente != null){
            query.setParameter("cliente", cliente);
        }
        int id =user.getAeropuerto().getCiudad().getIdciudad();
        query.setParameter("idCiudad", user.getAeropuerto().getCiudad().getIdciudad());        
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Itinerario c = (Itinerario) iter.next();
            Hibernate.initialize(c.getVuelo().getIdvuelo());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIddestino().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getSalidaest());
            Hibernate.initialize(c.getEnvio().getEstadoEnvio().getDescripcion());
            
            Hibernate.initialize(c.getEnvio().getCliente().getNombre());
            Hibernate.initialize(c.getEnvio().getCliente().getAppaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getApmaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getCorreo());
            Hibernate.initialize(c.getEnvio().getCliente().getTipoCorreo().getExtension());
            Hibernate.initialize(c.getEnvio());
            Hibernate.initialize(c.getEnvio().getAeropuerto());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad());
            Hibernate.initialize(c.getEnvio().getIdenvio());
            
            lstItinerarios.add(c);
        }
        
        tx.commit();
        session.close();
        lstItinerarios = listarVuelosBusquedaEntrada2(vuelo, estado, cliente, user, lstItinerarios);
        return lstItinerarios;
    }

        public ArrayList<Itinerario> listarVuelosBusquedaEntrada2(Vuelo vuelo, EstadoEnvio estado, String cliente, Usuario user, ArrayList<Itinerario> lstItinerarios){
        
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        
        String desc = "select itinerario from Vuelo vuelo, Itinerario itinerario where itinerario.vuelo.aeropuertoByIddestino.ciudad.idciudad = :idCiudad and itinerario.estadoItinerario.idestado = 2 and itinerario.tipoEscala.idtipo = 3 and vuelo.idvuelo = itinerario.vuelo.idvuelo and itinerario.envio.estadoEnvio <> 5 and itinerario.envio.estadoEnvio <> 4  ";//estado arribo (1), !envio estado cancelado (5)
        if (vuelo !=null){
            desc += "and vuelo.idvuelo = :idVuelo and itinerario.vuelo.idvuelo = :idVuelo ";
        }            
        if (estado !=null){
            desc += "and itinerario.envio.estadoEnvio.idestado = :idestado ";
        }            
        if (cliente != null){
            desc += "and (itinerario.envio.cliente.nombre like '%' || :cliente || '%' or itinerario.envio.cliente.apmaterno like '%' || :cliente || '%' or itinerario.envio.cliente.appaterno like '%' || :cliente || '%')";
            
        }                        
        
        Query query = session.createQuery(desc);
        
        if (vuelo !=null){
            query.setParameter("idVuelo", vuelo.getIdvuelo());
        }            
        if (estado !=null){
            query.setParameter("idestado", estado.getIdestado());
        }            
        if (cliente != null){
            query.setParameter("cliente", cliente);
        }                        
        query.setParameter("idCiudad", user.getAeropuerto().getCiudad().getIdciudad());
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Itinerario c = (Itinerario) iter.next();
            Hibernate.initialize(c.getVuelo().getIdvuelo());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIddestino().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getSalidaest());
            Hibernate.initialize(c.getEnvio().getEstadoEnvio().getDescripcion());
            
            Hibernate.initialize(c.getEnvio().getCliente().getNombre());
            Hibernate.initialize(c.getEnvio().getCliente().getAppaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getApmaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getCorreo());
            Hibernate.initialize(c.getEnvio().getCliente().getTipoCorreo().getExtension());
            Hibernate.initialize(c.getEnvio());
            Hibernate.initialize(c.getEnvio().getAeropuerto());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad());
            Hibernate.initialize(c.getEnvio().getIdenvio());
            
            
            lstItinerarios.add(c);
        }
        
        tx.commit();
        session.close();        
        
        return lstItinerarios;
    }

    
    public ArrayList<Itinerario> listarVuelosBusquedaSalida(Vuelo vuelo, EstadoEnvio estado, String cliente, Usuario user){
        ArrayList<Itinerario> lstItinerarios = new ArrayList<>();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        
        String desc = "select itinerario from Vuelo vuelo, Itinerario itinerario where itinerario.vuelo.aeropuertoByIdorigen.ciudad.idciudad = :idCiudad and itinerario.estadoItinerario.idestado = 2 and vuelo.idvuelo = itinerario.vuelo.idvuelo ";//estado arribo (2)
        if (vuelo !=null){
            desc += "and vuelo.idvuelo = :idVuelo and itinerario.vuelo.idvuelo = :idVuelo ";
        }            
        if (estado !=null){
            desc += "and itinerario.envio.estadoEnvio.idestado = :idestado ";
        }            
        if (cliente != null){
            desc += "and (itinerario.envio.cliente.nombre like '%' || :cliente || '%' or itinerario.envio.cliente.apmaterno like '%' || :cliente || '%' or itinerario.envio.cliente.appaterno like '%' || :cliente || '%')";
            
        }                        
        
        Query query = session.createQuery(desc);
        
        if (vuelo !=null){
            query.setParameter("idVuelo", vuelo.getIdvuelo());
        }            
        if (estado !=null){
            query.setParameter("idestado", estado.getIdestado());
        }            
        if (cliente != null){
            query.setParameter("cliente", cliente);
        }                        
        query.setParameter("idCiudad", user.getAeropuerto().getCiudad().getIdciudad());
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Itinerario c = (Itinerario) iter.next();
            Hibernate.initialize(c.getVuelo().getIdvuelo());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIddestino().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getSalidaest());
            Hibernate.initialize(c.getEnvio().getEstadoEnvio().getDescripcion());
            
            Hibernate.initialize(c.getEnvio().getCliente().getNombre());
            Hibernate.initialize(c.getEnvio().getCliente().getAppaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getApmaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getCorreo());
            Hibernate.initialize(c.getEnvio().getCliente().getTipoCorreo().getExtension());
            Hibernate.initialize(c.getEnvio());
            Hibernate.initialize(c.getEnvio().getAeropuerto());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad());
            Hibernate.initialize(c.getEnvio().getIdenvio());
            lstItinerarios.add(c);
        }
        
        tx.commit();
        session.close();
        
        lstItinerarios = listarVuelosBusquedaSalida2(vuelo, estado, cliente, user, lstItinerarios);
        
        return lstItinerarios;
    }
    ////
    
    public ArrayList<Itinerario> listarVuelosBusquedaSalida2(Vuelo vuelo, EstadoEnvio estado, String cliente, Usuario user, ArrayList<Itinerario> lstItinerarios){
        
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();        
        
        String desc = "select itinerario from Vuelo vuelo, Itinerario itinerario where itinerario.vuelo.aeropuertoByIdorigen.ciudad.idciudad = :idCiudad and itinerario.estadoItinerario.idestado = 1 and vuelo.idvuelo = itinerario.vuelo.idvuelo and itinerario.envio.estadoEnvio <> 5  ";//estado arribo (1), !envio estado cancelado (5)
        if (vuelo !=null){
            desc += "and vuelo.idvuelo = :idVuelo and itinerario.vuelo.idvuelo = :idVuelo ";
        }            
        if (estado !=null){
            desc += "and itinerario.envio.estadoEnvio.idestado = :idestado ";
        }            
        if (cliente != null){
            desc += "and (itinerario.envio.cliente.nombre like '%' || :cliente || '%' or itinerario.envio.cliente.apmaterno like '%' || :cliente || '%' or itinerario.envio.cliente.appaterno like '%' || :cliente || '%')";
            
        }                        
        
        Query query = session.createQuery(desc);
        
        if (vuelo !=null){
            query.setParameter("idVuelo", vuelo.getIdvuelo());
        }            
        if (estado !=null){
            query.setParameter("idestado", estado.getIdestado());
        }            
        if (cliente != null){
            query.setParameter("cliente", cliente);
        }                        
        query.setParameter("idCiudad", user.getAeropuerto().getCiudad().getIdciudad());
        List lista = query.list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Itinerario c = (Itinerario) iter.next();
            Hibernate.initialize(c.getVuelo().getIdvuelo());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIddestino().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getSalidaest());
            Hibernate.initialize(c.getEnvio().getEstadoEnvio().getDescripcion());           
            
            Hibernate.initialize(c.getEnvio().getCliente().getNombre());
            Hibernate.initialize(c.getEnvio().getCliente().getAppaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getApmaterno());
            Hibernate.initialize(c.getEnvio().getCliente().getCorreo());
            Hibernate.initialize(c.getEnvio().getCliente().getTipoCorreo().getExtension());
            Hibernate.initialize(c.getEnvio());
            Hibernate.initialize(c.getEnvio().getAeropuerto());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad());
            Hibernate.initialize(c.getEnvio().getAeropuerto().getCiudad().getDescripcion());
            Hibernate.initialize(c.getVuelo().getAeropuertoByIdorigen().getCiudad());
            Hibernate.initialize(c.getEnvio().getIdenvio());
            lstItinerarios.add(c);
        }
        
        tx.commit();
        session.close();        
        
        return lstItinerarios;
    }
     
    ///////Administrar entregas
    public void EntregarEnvio(Usuario user, Envio envio, Itinerario itinerario){                  //
        Inventario inventario = new Inventario();
        inventario.setAeropuerto(itinerario.getVuelo().getAeropuertoByIddestino());
        TipoMovimiento m = new TipoMovimiento();        
        m.setIdtipomov(Constante.TIPO_MOVIMIENTO_SALIDA);
        inventario.setTipoMovimiento(m);
        inventario.setUsuario(user);
        inventario.setEnvio(itinerario.getEnvio());
        inventario.setFechareg(new Date());
        EstadoEnvio estado = new EstadoEnvio();
        estado.setIdestado(Constante.ESTADO_ENVIO_ENTREGADO);

        envio.setEstadoEnvio(estado);
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        
        session.save(inventario);
        session.update(envio);
        tx.commit();
        session.close();
    }

    /////////////Alertar Envios
    public void GenerarNotadeCredito(Usuario user, Envio envio, int paquetes){
        NotaCredito nota = new NotaCredito();
        nota.setEnvio(envio);
        EstadoNotaCredito estado = new EstadoNotaCredito();
        estado.setIdestado(Constante.ESTADO_NOTA_CREDITO_PENDIENTE);        

        nota.setEstadoNotaCredito(estado);
        nota.setFechareg(new Date());
        nota.setUsuario(user);
        envio.setNumpacklost(paquetes + envio.getNumpacklost());
        actualizarEstadoPaquetesPerdidos(envio, paquetes);
        nota.setMonto((envio.getCosto()/envio.getNumpack())*envio.getNumpacklost());
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        //Generar nota de credito
        session.save(nota);
        session.update(envio);

        tx.commit();
        session.close();
        
    }
    
    public Itinerario buscarItinerario(){
        Itinerario itene = new Itinerario();
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        
        List lista = session.createQuery("from Itinerario").list();
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            itene = (Itinerario) iter.next(); 
            Hibernate.initialize(itene.getEnvio().getCliente().getNombre());
            Hibernate.initialize(itene.getEnvio().getCliente().getAppaterno());
            Hibernate.initialize(itene.getEnvio().getCliente().getApmaterno());
            Hibernate.initialize(itene.getEnvio().getCliente().getCorreo());
            Hibernate.initialize(itene.getEnvio().getAeropuerto());
            Hibernate.initialize(itene.getEnvio().getCliente().getTipoCorreo().getExtension());
            Hibernate.initialize(itene.getEnvio().getReceptor());
            
            Hibernate.initialize(itene.getVuelo().getAeropuertoByIddestino());
            Hibernate.initialize(itene.getEnvio());
            Hibernate.initialize(itene.getVuelo().getAeropuertoByIdorigen().getCiudad());
            Hibernate.initialize(itene.getEnvio().getIdenvio());
        }
        
        tx.commit();
        session.close();
        return itene;
    }

    public void RegistrarNotaEntrada(Itinerario itinerario, Usuario user) {
        EstadoItinerario estado = new EstadoItinerario();
        estado.setIdestado(Constante.ESTADO_ITINERARIO_ARRIBO);
        itinerario.setEstadoItinerario(estado);
        Itinerario iter2 = null;
        if (itinerario.getTipoEscala().getIdtipo()!=Constante.TIPO_ESCALA_FIN){
            iter2 = buscaSiguiente(itinerario);
            estado.setIdestado(Constante.ESTADO_ITINERARIO_PENDIENTE);
            iter2.setEstadoItinerario(estado);
        }
        Inventario inventario = new Inventario();
        TipoMovimiento m = new TipoMovimiento();
        m.setIdtipomov(Constante.TIPO_MOVIMIENTO_ENTRADA);
        Aeropuerto aero = buscaAeropuerto(user.getAeropuerto().getCiudad()); 
        aero.setNumpack(aero.getNumpack()+itinerario.getEnvio().getNumpack()-itinerario.getEnvio().getNumpacklost());
        inventario.setAeropuerto(aero);
        inventario.setUsuario(user);
        inventario.setEnvio(itinerario.getEnvio());
        inventario.setTipoMovimiento(m);
        inventario.setFechareg(new Date());

        actualizarEstadoPaquetes(itinerario.getEnvio(), Constante.ESTADO_PAQUETE_ALMACEN);

        Session session = HibernateUtil.getSessionFactory().openSession();        
        Transaction tx =  session.beginTransaction();
        session.update(itinerario);
        session.save(inventario);
        session.update(aero);
        if (iter2 != null){
         session.update(iter2);   
        }   
        tx.commit();
        session.close();        
    }
    
    public void actualizarEstadoPaquetes(Envio envio, int estado){
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        EstadoPaquete estadop = new EstadoPaquete();
        estadop.setIdestado(estado);
        Query query = session.createQuery("select paquete from Paquete paquete where paquete.estadoPaquete.idestado <> 3 and paquete.envio.idenvio = :idEnvio" ); //3 perdido
        query.setParameter("idEnvio", envio.getIdenvio());
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Paquete c = (Paquete) iter.next();
            c.setEstadoPaquete(estadop);
            session.update(c);
        }        
        tx.commit();
        session.close();        
        
    }
    
    public void actualizarEstadoPaquetesPerdidos(Envio envio, int estado){        
        int i = 0;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        EstadoPaquete estadop = new EstadoPaquete();
        estadop.setIdestado(Constante.ESTADO_PAQUETE_PERDIDO);
        Query query = session.createQuery("select paquete from Paquete paquete where paquete.estadoPaquete.idestado <> 3 and paquete.envio.idenvio = :idEnvio" ); //3 perdido
        query.setParameter("idEnvio", envio.getIdenvio());
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext();i++) {    
            Paquete c = (Paquete) iter.next();
            if (i<estado){
                c.setEstadoPaquete(estadop);
                session.update(c);
            }
        }        
        tx.commit();
        session.close();        
        
    }

    public void RegistrarNotaSalida(Itinerario itinerario, Usuario user) {
        EstadoItinerario estado = new EstadoItinerario();      
        estado.setIdestado(Constante.ESTADO_ITINERARIO_RECORRIDO);
        itinerario.setEstadoItinerario(estado);                
        Inventario inventario = new Inventario();
        TipoMovimiento m = new TipoMovimiento();
        m.setIdtipomov(Constante.TIPO_MOVIMIENTO_SALIDA);
        Aeropuerto aero = buscaAeropuerto(user.getAeropuerto().getCiudad()); 
        aero.setNumpack(aero.getNumpack()-itinerario.getEnvio().getNumpack()+itinerario.getEnvio().getNumpacklost());
        inventario.setAeropuerto(aero);
        inventario.setUsuario(user);
        inventario.setEnvio(itinerario.getEnvio());
        inventario.setTipoMovimiento(m);
        inventario.setFechareg(new Date());

        actualizarEstadoPaquetes(itinerario.getEnvio(), Constante.ESTADO_PAQUETE_TRANSPORTE);

        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        session.update(itinerario);
        session.save(inventario);
        session.update(aero);                  
        tx.commit();
        session.close();     
    }

    public ArrayList<Paquete> GenerarPaquetes(Envio envio) {
        ArrayList<Paquete> lstPaquetes = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        Query query = session.createQuery("select paquete from Paquete paquete where paquete.estadoPaquete.idestado <> 4 and paquete.envio.idenvio = :idEnvio" ); //4 entregado
        query.setParameter("idEnvio", envio.getIdenvio());
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Paquete c = (Paquete) iter.next();
            Hibernate.initialize(c.getEnvio().getIdenvio());
            Hibernate.initialize(c.getIdpaquete());
            Hibernate.initialize(c.getEstadoPaquete().getDescripcion());
            lstPaquetes.add(c);            
        }                                
        tx.commit();
        session.close();   
        return lstPaquetes;
    }
    
    public Ciudad GetCiudadOrigen(Envio envio) {
        int i = 1;
        Ciudad Origen = new Ciudad();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        Query query = session.createQuery("select vuelo from Vuelo vuelo, Itinerario itinerario where itinerario.vuelo.idvuelo = vuelo.idvuelo and itinerario.envio.idenvio = :idEnvio" ); //- estado?
        query.setParameter("idEnvio", envio.getIdenvio());
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext();i++) {    
            Vuelo c = (Vuelo) iter.next();
            if (i==1){
                Origen = c.getAeropuertoByIdorigen().getCiudad();
                Hibernate.initialize(c.getAeropuertoByIdorigen().getCiudad().getDescripcion());
            }            
        }                                
        tx.commit();
        session.close();   
        return Origen;
    }
    
    public Ciudad GetCiudadDestino(Envio envio) {        
        Ciudad Destino = new Ciudad();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        Query query = session.createQuery("select vuelo from Vuelo vuelo, Itinerario itinerario where itinerario.vuelo.idvuelo = vuelo.idvuelo and itinerario.envio.idenvio = :idEnvio" ); //- estado?
        query.setParameter("idEnvio", envio.getIdenvio());
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Vuelo c = (Vuelo) iter.next();            
            Destino = c.getAeropuertoByIddestino().getCiudad();
            Hibernate.initialize(c.getAeropuertoByIdorigen().getCiudad().getDescripcion());            
        }                                
        tx.commit();
        session.close();   
        return Destino;
    }

    public void GenerarItinerario(Envio envio, Solucion lstVuelos) {
             
        Itinerario iter = new Itinerario();
        EstadoItinerario estado = new EstadoItinerario();
        TipoEscala tipo = new TipoEscala();        
        iter.setEnvio(envio);
        iter.setEstadoItinerario(estado);
        int escala = 1;
        
        Pronostico pronosticoSalida = new Pronostico();
        Vuelo v1 = new Vuelo(lstVuelos.get(0));
        pronosticoSalida.setAeropuerto(v1.getAeropuertoByIdorigen()); //AeropuertoDestino
        pronosticoSalida.setFechareg(v1.getLlegadaest()); //salidaEstimada
        pronosticoSalida.setNropack(envio.getNumpack());
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();       
        session.save(pronosticoSalida);
        tx.commit();
        session.close();
        
        for (int i = 0;i< lstVuelos.size();i++){
            if (escala == 1){
                tipo.setIdtipo(Constante.TIPO_ESCALA_INICIO);
                estado.setIdestado(Constante.ESTADO_ITINERARIO_PENDIENTE);
                if (escala == lstVuelos.size()){
                    tipo.setIdtipo(Constante.TIPO_ESCALA_FIN);
                }
            } else if (escala == lstVuelos.size()){
                tipo.setIdtipo(Constante.TIPO_ESCALA_FIN);
                estado.setIdestado(Constante.ESTADO_ITINERARIO_ESPERA);
            }
            else {
                tipo.setIdtipo(Constante.TIPO_ESCALA_PASO);
                estado.setIdestado(Constante.ESTADO_ITINERARIO_ESPERA);
            }
            iter.setTipoEscala(tipo);
            iter.setSeq(escala);
            
            // Crear constructor copia
            Vuelo v = new Vuelo(lstVuelos.get(i));
            iter.setEstadoItinerario(estado);
            iter.setVuelo(v);
            InsertarItinerario(iter);
            
            //Actualiza tabla pronostico
            actualizarPronostico(v, envio.getNumpack());
            
            //Actualiza escala
            escala++;
        }

    }
    
    public void InsertarItinerario(Itinerario iter){
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        session.save(iter);
        tx.commit();
        session.close();  
    }

    public Aeropuerto GetAeropuerto(int idciudad) {        
        Aeropuerto aer = new Aeropuerto();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();
        Query query = session.createQuery("select aero from Aeropuerto aero where aero.ciudad.idciudad = :idCiudad" ); //- estado?
        query.setParameter("idCiudad", idciudad);
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Aeropuerto c = (Aeropuerto) iter.next();            
            aer = c;
            Hibernate.initialize(c.getIdaeropuerto());            
        }                                
        tx.commit();
        session.close();   
        return aer;
    }
    public void CancelarEnvio(Envio envio,int idEstado){
        EstadoEnvio estado = new EstadoEnvio();
        estado.setIdestado(idEstado);//5 cancelado, 6 cancelado por cliente
        envio.setEstadoEnvio(estado);        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();                
        session.update(envio);        
        tx.commit();
        session.close();
        
    }
    
    public void actualizarPronostico (Vuelo v, int numPack) {
        //Abrir sesión
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();                
            
        //Prepara pronostico
        Pronostico pronosticoEntrada = new Pronostico();
        pronosticoEntrada.setAeropuerto(v.getAeropuertoByIdorigen()); //AeropuertoOrigen
        pronosticoEntrada.setFechareg(v.getSalidaest()); //salidaEstimada
        pronosticoEntrada.setNropack((-1)*numPack);
        
        Pronostico pronosticoSalida = new Pronostico();
        pronosticoSalida.setAeropuerto(v.getAeropuertoByIddestino()); //AeropuertoDestino
        pronosticoSalida.setFechareg(v.getLlegadaest()); //salidaEstimada
        pronosticoSalida.setNropack(numPack);
        
        //Ejecutar inserts
        session.save(pronosticoEntrada);
        session.save(pronosticoSalida);
        //Confirmar transacción y cerrar sesión
        tx.commit();
        session.close();
    }  

    private Itinerario buscaSiguiente(Itinerario itinerario) {
        Itinerario iter2 = new Itinerario();
        int valor;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();                        
        Query query = session.createQuery("select iter from Itinerario iter where iter.iditinerario = :idItinerario "); //- estado?
        valor =itinerario.getIditinerario();
        valor++;
        query.setParameter("idItinerario", valor);
        List lista = query.list();          
        for ( Iterator iter = lista.iterator(); iter.hasNext(); ) {    
            Itinerario c = (Itinerario) iter.next();            
            iter2 = c;            
        }                                
        tx.commit();
        session.close();
        return iter2;
    }

    public boolean lugarfinal(Itinerario itinerario) {        
        return itinerario.getTipoEscala().getIdtipo() == Constante.TIPO_ESCALA_FIN;
    }
}
